﻿using System.Collections.Generic;
using System;

namespace XchangeStreamer.Types
{
    public static class ResourcePool<T> where T : IResource, new()
    {
        #region Private Fields

        private static T[] pool;
        private static Queue<T> available;
        
        #endregion

        #region Const.

        static ResourcePool()
        {
            Init(10000);
        }

        #endregion

        #region Public Methods

        public static T Accquire()
        {
            T resource = available.Dequeue();
            resource.IsResourceUsed = true;
            return resource;
        }

        public static void Release(T resource)
        {
            if (resource == null)
            {
                throw new ArgumentNullException("Resource is null.");
            }

            if (available.Count == pool.Length)
            {
                throw new ArgumentException("Pool is full.");
            }

            if (!resource.IsResourceUsed)
            {
                throw new InvalidOperationException("Attempt to return free resource.");
            }

            resource.IsResourceUsed = false;
            available.Enqueue(resource);
        }

        //public static void SetPoolSize(int size)
        //{
        //    if (size == pool.Length)
        //    {
        //        return;
        //    }

        //    Array.Resize<T>(ref pool, size);
        //}

        public static int GetPoolSize()
        {
            return pool.Length;
        }

        #endregion

        #region Private Methods

        private static void Init(int capacity)
        {
            pool = new T[capacity];
            available = new Queue<T>(capacity);

            for (int i = 0; i < capacity; i++)
            {
                var resource = new T();
                pool[i] = resource;
                available.Enqueue(resource);
            }
        }

        #endregion
    }
}
